<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
<script>
// 代码 -> https://segmentfault.com/a/1190000022677985
// https://github.com/YvetteLau/Blog/issues/37

// TODO: 1. 原型链继承
  // 原理: 将父类的实例赋值给子类的 prototype 来实现
  // 缺点: 引用类型的原型属性会被所有实例共享(值类型在原型中定义, 实例无法获取), 因此所有子类共享父类构造函数中的引用类型, 其中一个子类实例修改, 会导致所有都修改
// TODO: 2. 构造函数继承
  // 原理: 将父类的构造函数在子类的构造函数中执行, 并传入 this 来实现
  // 优点: 解决了原型链继承中, 引用类型共享的问题
  // 缺点: 所有的方法都定义在构造函数中, 每次都要重建(原型链继承, 都写在原型上, 则不需要重新创建方法)
// TODO: 3. 组合继承
  // 原理: 同时结合原型链继承和构造函数继承
  // 优点: 解决了原型链继承中引用类型共享的问题, 也避免了方法被创建多次的问题
  // 缺点: 父类构造函数被调用两次(子类构造函数中调用, 将父类的实例赋值给子类的 prototype 的时候调用), 
        // 如果子类和父类的构造函数中出现同名的属性, 将会同时存在, 只不过子类会优先读取自己的属性
// TODO: 4. 寄生组合继承
  // 原理: 通过一个空的构造函数来中转, 将父类的 prototype 赋值给空的构造函数的 prototype, new 这个空构造函数, 并赋值给子类的 prototype(相当于复制了一份父类的 prototype 对象)
  // 优点: 解决了上面三种的问题
  // 缺点: todo...
// TODO: 5. ES6 class 继承
  // 原理: 子类通过 extends 继承, 并在子类构造函数中 super(), 相当于 Parent.prototype.constructor.call(this, props)
  // super 的使用 -> https://juejin.cn/post/6844903638674980872
</script>
</body>
</html>